package VueBelote;


//
// IUT de Nice / Departement informatique / Module APO-Java
// Annee 2011_2012 - Composants generiques
//
// Classe VuePanneauG - Panneau generique de visualisation (MVC - partie Vue)
//
// Edition Draft    : mise en place du panneau
//
//    + Version 0.0.0	: chargement du fichier de configuration
//    + Version 0.1.0	: ajout d'une methode de chargement d'une image 
//    + Version 0.2.0   : ajout d'une surcharge de la methode paint
//    + Version 0.3.0   : modification de la reference fournie au mediaTracker
//                        (OPERATIONNELLE !) 
//    + Version 0.4.0   : demonstrateur (main) avec deux instances
//    + Version 0.5.0   : demonstrateur avec une vignette  
//
// Edition A        : visualisation d'une image de fond
//
//    + Version 1.0.0   : image parametree depuis le fichier de configuration
//    + Version 1.1.0   : ajout de la methode modifierImage
//    + Version 1.2.0   : le panneau s'accroche automatiquement au cadre support
//    + Version 1.3.0   : simplification du second constructeur normal par
//                        invocation du premier
//    + Version 1.4.0   : ajout d'un constructeur pour le chargement automatique
//                        de la configuration
//    + Version 1.5.0   : factorisation des traitements communs au second et au 
//                        troisieme constructeur
//
// Edition B        : dessin d'un titre dans un panneau
//
//    + Version 2.0.0   : limitee aux panneaux sans image de fond
//    + Version 2.1.0   : extension aux panneaux avec image de fond
//
// Edition C        : gestion de la souris par un controleur approprie
//
//    + Version 3.0.0   : "call back" independantes du contexte graphique du
//                        panneau observe et en classe interne
//    + Version 3.1.0   : externalisation des "call back" attachees a la
//                        gestion de toutes les actions souris dans un
//                        controleur de panneau
//    + Version 3.2.0   : externalisation complete du controleur (modele MVC),
//                        qui devient une classe generique a part entiere
//    + Version 3.3.0   : memorisation du controleur sous forme d'attribut et 
//                        modification du point d'entree pour montrer les
//                        capacites d'espionnage
//
// Edition D        : evolutions fonctionnelles correlees avec celles du
//                    modele et/ou du controleur (MVC)
//
//    + Version 4.0.0   : externalisation du demonstrateur(main) pour faciliter 
//                        la gestion externe des trois composants MVC
//
// Edition E        : extension de la configuration a la description
//                    (eventuellement recursive) de sous panneaux
//
//    + Version 5.0.0   : ajout d'un attribut sousPanneaux et suppression
//                        provisoire de l'accrochage automatique au cadre 
//                        support
//    + Version 5.1.0   : mise en place d'un type generique pour l'hamecon et
//                        restauration de l'accrochage automatique au cadre 
//    + Version 5.2.0   : introduction de la methode ajouterPanneau
//    + Version 5.3.0   : ajout des accesseurs obtenirNbSP, obtenirOrigineSP,
//                        obtenirTailleSP et obtenirSP (protected !)
//    + Version 5.4.0   : les sous panneaux deviennent des instances de la
//                        classe PanneauG
//    + Version 5.5.0   : introduction d'une nouvelle signature de la methode 
//                        ajouterPanneau pour prolonger l'evolution precedente
//    + Version 5.6.0   : gestion d'une nouvelle cle "sousPanneaux" (eventuelle) 
//                        dans le fichier de configuration et ajout correle de 
//                        la methode setSP (N niveaux de sous panneaux)
//
// Edition F        : complements et extensions des methodes d'acces a tous les
//                    sous panneaux
// 
//    + Version 6.0.0   : extension de la methode modifierImage et ajout de la 
//                        methode presenceImage (limitation au niveau 1)
//    + Version 6.1.0   : extension de la methode obtenirSP a N niveaux de sous
//                        panneaux
//    + Version 6.2.0   : introduction de la methode installerSP pour l'ajout
//                        dynamique de sous panneaux (sans recurrence) dans le
//                        panneau principal (niveau 1 seulement)
//    + Version 6.3.0   : ajout d'une nouvelle signature de installerSP pour 
//                        une extension a tout sous panneau (sans recurrence)
//    + Version 6.4.0   : la methode ajouterPanneau devient privee 
//    + Version 6.5.0   : introduction de la methode deployerSP pour l'ajout 
//                        dynamique de sous panneaux (avec recurrence) dans le
//                        panneau principal
//    + Version 6.6.0   : ajout d'une nouvelle signature de deployerSP pour 
//                        une extension a tout sous panneau (avec recurrence)
//    + Version 6.7.0   : suppression de l'attribut controleur et modification
//                        du type du premier parametre du 3eme constructeur
//
// Edition G        : fin de la mise en conformite MVC
//
//    + Version 7.0.0   : introduction du prefixe Vue dans l'identificateur
//                        de la classe
//    + Version 7.1.0   : consolidation des constructeurs et mise en place
//                        d'une gestion d'exceptions
//    + Version 7.2.0   : extension des accesseurs de modification a tout
//                        sous panneau et ajout d'un accesseur public 
//                        reconfigurer (panneau principal et sous panneaux)
//                        + modification signature ajouterTitre
//                        + acces "protected" pour l'attribut hamecon
//                        + la methode chargerImage devient privee 
//    + Version 7.3.0   : acces "protected" pour la methode configurer
//           
// Auteur : A. Thuaire

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;

import javax.swing.JFrame;
import javax.swing.JPanel;

import Config.Config;
  
public class VuePanneauG extends JPanel {
protected Object hamecon;
private Image  imageFond;

private String texteTitre;
private Color  couleurTitre;
private Font   policeTitre;

private LinkedHashMap sousPanneaux;

// ---                                           Premier constructeur normal  

   public VuePanneauG (Object conteneur) throws Throwable {
   	
   	 // Controler la validite du parametre
   	 //
   	 if (conteneur == null) throw new Throwable ("-2.1");
   	
     // Memoriser l'hamecon vers le conteneur amont
     //
     hamecon= conteneur;
     
     // Definir un arriere plan jaune
     //
     setBackground(Color.yellow);
     
     // Definir un avant plan rouge
     //
     setForeground(Color.red);
     
     // Installer un gestionnaire de presentation par defaut
     //
     setLayout(new GridLayout(1,0));
     
     // Accrocher le panneau au conteneur amont
     //
     String typeConteneur= conteneur.getClass().getName();
     
     if (typeConteneur.equals("javax.swing.JFrame"))
        ((JFrame)conteneur).getContentPane().add(this);
        
     else ((VuePanneauG)conteneur).add(this); 
     
     // Creer la description interne des sous panneaux eventuels
     //
     sousPanneaux= new LinkedHashMap();
   } 
     	
// ---                                            Second constructeur normal 

   public VuePanneauG (Object hamecon, HashMap config) throws Throwable {
   	
      // Executer une configuration par defaut
      //
      this(hamecon);
      
      // Controler la validite du second parametre
      //
      if (config == null) throw new Throwable("-2.2");
   	     
      // Configurer le panneau cree
      //
      configurer(config);
   }
   
// ---                                         Troisieme constructeur normal 

   public VuePanneauG (Object hamecon, 
                       String chemin, 
                       String version) throws Throwable {
   	
     // Executer le premier constructeur normal
     //
     this(hamecon);
     
     // Controler la validite des deux derniers parametres
     //
     if (chemin == null) throw new Throwable("-2.2");
     if (version == null) throw new Throwable("-2.3");
     
      // Charger la configuration du panneau
      //
      Object config= Config.load(chemin, version);
      if (config == null) throw new Throwable("-3.2");
      
      // Controler la nature de la configuration
      //
      String typeD= config.getClass().getName();
      String refD = "java.util.HashMap";
      
      if (!typeD.equals(refD)) throw new Throwable("-3.5");
   	     
      // Configurer le panneau cree
      //
      configurer ((HashMap)config);
   }
   
// ---                                                 Methode setBackground
     
   public void setBackground(HashMap config) throws Throwable { 
   Object w;
   
      if (config == null) throw new Throwable ("-2.1");
   
      w= config.get("arrierePlan");
      if (w==null) {setBackground(Color.yellow); return;}
      setBackground((Color)w);
   }
      
   public void setBackground (String nomSP, 
                              HashMap config) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (config == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.setBackground (config);
   }
   
   public void setBackground (String nomSP, 
                              Color couleur) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (couleur == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.setBackground (couleur);
   }

// ---                                                 Methode setForeground
     
   public void setForeground(HashMap config) throws Throwable {
   Object w;
   
      if (config == null) throw new Throwable ("-2.1");
   
      w= config.get("avantPlan");
      if (w==null) {setForeground(Color.red); return;}
      setForeground((Color)w);
   }
   
   public void setForeground (String nomSP, 
                              HashMap config) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (config == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.setForeground (config);
   }
   
   public void setForeground (String nomSP, 
                              Color couleur) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (couleur == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.setForeground (couleur);
   }

// ---                                                       Methode setFont
     
   public void setFont(HashMap config) throws Throwable {
   Object w;
   
      if (config == null) throw new Throwable ("-2.1");
      
      w= config.get("police");
      if (w==null) return;
      setFont((Font)w);
   }
   
   public void setFont (String nomSP, 
                        HashMap config) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (config == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.setFont (config);
   }
   
   public void setFont (String nomSP, 
                        Font police) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (police == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.setFont (police);
   }
   
// ---                                                     Methode setLayout
     
   public void setLayout(HashMap config) throws Throwable { 
   Object w;
   
      if (config == null) throw new Throwable ("-2.1");
      
      w= config.get("placement");
      if (w==null) {setLayout(new GridLayout(1,0)); return;}
      setLayout((LayoutManager)w);
   }
   
   public void setLayout (String nomSP, 
                          HashMap config) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (config == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.setLayout (config);
   }
   
   public void setLayout (String nomSP, 
                          LayoutManager placement) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (placement == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.setLayout (placement);
   }
 
// ---                                                      Methode setImage
     
   public void setImage(HashMap config) throws Throwable { 
   Object w;
   
      if (config == null) throw new Throwable ("-2.1");
      
      w= config.get("image");
      if (w !=null) {chargerImage((String)w);}
   } 
   
   public void setImage (String nomSP, 
                         HashMap config) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (config == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.setImage (config);
   } 
   
   public void setImage (String nomSP, 
                         String chemin) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (chemin == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.chargerImage (chemin);
   } 
   
// ----                                                 Methode chargerImage 
   
   private void chargerImage(String cheminImage) throws Throwable {
   	
   	  // Controler la validite du parametre
   	  //
   	  if (cheminImage == null) throw new Throwable("-2.1");
   	     
      // Charger une image de fond depuis un fichier de type jpeg
      //
      imageFond= Toolkit.getDefaultToolkit().getImage(cheminImage);
      if (imageFond == null) throw new Throwable("-3.3");
  	
      // Construire un media tracker pour controler le chargement de l'image
      //
      MediaTracker mt= new MediaTracker(this);
   	  
      // Attendre la fin du chargement effectif de l'image
      //
      mt.addImage(imageFond,0);
      try{mt.waitForAll();}
      catch(Exception e){}
   } 
   
// ----                                                        Methode paint

   @Override
public void paint (Graphics g) {
   	
      super.paint(g);
      
      // Dessiner l'image de fond eventuelle
      //
      if (imageFond != null) {
         g.drawImage(imageFond, 0, 0, getWidth(), getHeight(), null);
      } 
      
      // Dessiner le titre eventuel
      //
      if (texteTitre != null) dessinerTitre(g); 	
   }
   
// ---                                                 Methode modifierImage

   public void modifierImage(String cheminImage) throws Throwable { 
   
      if (cheminImage == null) {imageFond= null; repaint(); return;}
      
      chargerImage(cheminImage);
      
      repaint();
   }
   
   public void modifierImage(String nomSP, 
                             String cheminImage) throws Throwable { 
      
      // Traiter le cas particulier du panneau principal
      //
      if (nomSP == null) {modifierImage (cheminImage); repaint();return;}
      
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification d'image sur la cible
      //
      cible.modifierImage (cheminImage);
      cible.repaint();
   }
   
// ---                                                    Methode configurer  

   protected void configurer (HashMap config) throws Throwable {

      setBackground(config);
      setForeground(config);
      setFont(config);
      setLayout(config);
      setImage(config);
      setTitre(config);
      setSP(config);
   }
   
// ---                                                     Methode setTitre
     
   public void setTitre(HashMap config) throws Throwable {
   Object w;
   
      if (config == null) throw new Throwable ("-2.1");
      
      w= config.get("titre");
      if (w==null) return;
      ajouterTitre((String)w);
   }
   
   public void setTitre (String nomSP, 
                         HashMap config) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (config == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.setTitre (config);
   } 
   
   public void setTitre (String nomSP, 
                         String titre) throws Throwable {

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (titre == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.ajouterTitre (titre);
   } 
   
// ---                                                  Methode ajouterTitre
   
   public void ajouterTitre(String titre) throws Throwable {
      	
      // Controler la validite du parametre
      //
      if (titre == null) throw new Throwable ("-2.1");
      	
      // Renseigner les attributs associes au titre
      //
      texteTitre  = titre;
      	
      // Repeindre le panneau
      //
      repaint();
   }
   
   public void ajouterTitre (String nomSP, 
                             String titre) throws Throwable {
   Object w;

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (titre == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.ajouterTitre (titre);
   } 
   
// ---                                                  Methode ajouterTitre
   
   public void ajouterTitre (String titre, Color couleur, 
                             Font police) throws Throwable {
      	
      // Controler la validite des parametres
      //
      if (titre == null)   throw new Throwable ("-2.1");
      if (couleur == null) throw new Throwable ("-2.2");
      if (police == null)  throw new Throwable ("-2.3");
      	
      // Renseigner les attributs associes au titre
      //
      texteTitre  = titre;
      couleurTitre= couleur;
      policeTitre = police;
      	
      // Repeindre le panneau
      //
      repaint();
   }
   
   public void ajouterTitre (String nomSP, 
                             String titre, 
                             Color couleur, 
                             Font police) throws Throwable {
   Object w;

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (titre == null) throw new Throwable ("-2.2");
      if (couleur == null) throw new Throwable ("-2.3");
      if (police == null)  throw new Throwable ("-2.4");
      	
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.ajouterTitre (titre, couleur, police);
   } 
      
// ---                                                  Methode modifierTitre
   
   public void modifierTitre (String titre) {
      	
      if (titre != null) texteTitre  = titre; 
      else {
      		
         texteTitre  = null; 
         couleurTitre= null;
      	 policeTitre = null;
      }
      	
      repaint();
   }
   
   public void modifierTitre (String nomSP, 
                              String titre) throws Throwable {
   Object w;

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (titre == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Appliquer la modification sur la cible
      //
      cible.modifierTitre (titre);
   } 
      
// ---                                                  Methode dessinerTitre
   
   private void dessinerTitre(Graphics g) {
      	
      // Controler la presence d'un titre
      //
      if (texteTitre == null) return;
         
      // Calculer les dimensions du titre
      //    
      FontMetrics fm= g.getFontMetrics();
        
      int largeurTitre= fm.stringWidth(texteTitre);
      int hauteurTitre= fm.getHeight();
         
      // Modifier la couleur courante de dessin dans le panneau
      //
      if (couleurTitre != null) g.setColor(couleurTitre);
         
      // Modifier la police courante du panneau
      //
      if (policeTitre != null) g.setFont(policeTitre);
         
      // Traiter le cas de l'absence d'image de fond
      //
      if (imageFond == null) {
   	  	
         // Calculer les coordonnees du centre du panneau
         //
   	     int abscisseCentre= getWidth()/2;
   	     int ordonneeCentre= getHeight()/2;
         
         // Dessiner le texte
         //
         g.drawString(texteTitre, (getWidth()-largeurTitre)/2, 
                                  (getHeight()-hauteurTitre)/2);
   	  }
   	  else {
   	
         // Traiter le cas de la presence d'une image de fond
         //
         g.drawString(texteTitre, (getWidth()-largeurTitre)/2, 
                                      getHeight()-10 );
      }
   } 
   
// ---                                             Methode ajouterControleur
   
   public void ajouterControleur (Object c) throws Throwable { 
   	
   	  if (c == null) throw new Throwable("-2.1");
         
      addMouseListener((MouseListener) c);
      addMouseMotionListener((MouseMotionListener)c);  
   }
   
   public void ajouterControleur (String nomSP, 
                                  Object c) throws Throwable { 
   Object w;

      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable ("-2.1"); 
      if (c == null) throw new Throwable ("-2.2");
   
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP (nomSP);
      if (cible == null) throw new Throwable("-3.4");
      
      // Ajouter le controleur a la cible
      //
      cible.ajouterControleur (c);
   } 
   
// ---                                                Methode ajouterPanneau
     
   private void ajouterPanneau (String nomPanneau, JPanel p) {                                            	
            
      // Memoriser le panneau cible dans le dictionnaire des panneaux
      //
      sousPanneaux.put(nomPanneau, p);
      
      // Ajouter le panneau au conteneur amont
      //
      add(p);                                   	
   }
   
   private void ajouterPanneau (String nomPanneau, 
                                HashMap config) throws Throwable {                                             	
   VuePanneauG p;
            
      // Creer le panneau cible
      //
      if (config == null) p= new VuePanneauG(this); 
      else p= new VuePanneauG(this, config);                                              	
                  
      // Ajouter le panneau au nouveau conteneur amont
      //
      ajouterPanneau(nomPanneau, p);                                    	
   }
   
// ---                                                   Methode obtenirNbSP
     
   public int obtenirNbSP () {return sousPanneaux.size();}
      
// ---                                              Methode obtenirOrigineSP
     
   public Point obtenirOrigineSP (String nomPanneau) throws Throwable {                                            	
            
      if (nomPanneau == null) throw new Throwable("-2.1");
      
      VuePanneauG cible= (VuePanneauG)sousPanneaux.get(nomPanneau); 
      if (cible == null) throw new Throwable("-3.4");
      
      return cible.getLocation();                              	
   }
   
// ---                                              Methode obtenirTailleSP
     
   public Dimension obtenirTailleSP (String nomPanneau) throws Throwable {                                            	
            
      if (nomPanneau == null) throw new Throwable("-2.1");
      
      VuePanneauG cible= (VuePanneauG)sousPanneaux.get(nomPanneau); 
      if (cible == null) throw new Throwable("-3.4");
      
      return cible.getSize();                              	
   }
   
// ---                                                    Methode obtenirSP
     
   protected VuePanneauG obtenirSP (String nomSP) throws Throwable {                                            	
            
      // Controler la validite du parametre
      //
      if (nomSP == null) throw new Throwable("-2.1");
      
      // Parcourir l'arborescence de tous les sous panneaux
      //
      Iterator i=sousPanneaux.keySet().iterator();
      String cle=null;
      VuePanneauG associe= null;
      VuePanneauG resultat= null;
   	     	
      while(i.hasNext()) {

         // Acquerir la cle courante
         //
         cle=(String)i.next();
         
         // Acquerir l'associe courant
         //
         associe= (VuePanneauG)sousPanneaux.get(cle);
         
         // Traiter la premiere condition d'arret de la recursion  
         //
         if (cle.equals(nomSP)) return associe;
         
         // Traiter le niveau immediatement inferieur eventuel (recursion)
         //
         if (associe  != null) resultat= associe.obtenirSP(nomSP);
         if (resultat != null) return resultat;
      }
      
      // Traiter le cas ou la cible est absente de l'arborescence
      //
      return null;                               	
   }
   
// ---                                                        Methode setSP
 
   private void setSP(HashMap config) throws Throwable {
   Object w;
   
      // Controler la presence eventuelle de la cle "sousPanneaux"
      //
      if (config == null) throw new Throwable("-2.1");
      w= config.get("sousPanneaux");
      if (w==null) return;
      
      // Controler la nature de l'associe
      //
      String typeD= w.getClass().getName();
      String refD = "java.util.LinkedHashMap";
      
      if (!typeD.equals(refD)) throw new Throwable("-3.5");
      
      // Convertir l'associe pour le parcourir
      //
      LinkedHashMap description= (LinkedHashMap)w;
      
      // Parcourir la description des sous panneaux
      // 
      Iterator i=description.keySet().iterator();
      String cle=null;
      String version= null;
      String chemin= null;
      HashMap configCourante= null;
   	     	
      while(i.hasNext()) {

         // Acquerir la cle courante
         //
         cle=(String)i.next();
         
         // Acquerir l'associe courant
         //
         version= (String)description.get(cle);
         
         // Designer le fichier de configuration du sous panneau courant 
         //
         chemin= "Config/ConfigSP" + cle;
         
         // Charger la configuration du sous panneau courant
         //
         configCourante= (HashMap)Config.load(chemin, version);
         
         // Ajouter le sous panneau courant au panneau cible
         //
         ajouterPanneau(cle, configCourante);
      }
   }
   
// ---                                                Methode presenceImage
     
   public boolean presenceImage () { return imageFond != null;}
   
   public boolean presenceImage (String nomSP) throws Throwable {  
   
      // Traiter le cas particulier du panneau principal
      //
      if (nomSP == null) return presenceImage();
      
      // Obtenir la reference Java du sous panneau cible
      //
      VuePanneauG cible= obtenirSP(nomSP);
      if (cible == null) return false;
               
      // Rechercher la presence d'une image sur le sous panneau cible
      //
      return cible.presenceImage ();
   }

// ---                                                  Methode installerSP
     
   public boolean installerSP (LinkedHashMap description) throws Throwable { 
   
      // Controler la validite des parametres
      //
      if (description == null) throw new Throwable("-2.1");
      
      // Parcourir la description des sous panneaux
      // 
      Iterator i=description.keySet().iterator();
      String cle=null;
      Object associe= null;
      String typeA= null;
      String refA = "java.util.HashMap";
      Object configCourante= null;
   	     	
      while(i.hasNext()) {

         // Acquerir la cle courante
         //
         cle=(String)i.next();
         
         // Acquerir l'associe courant
         //
         associe= description.get(cle);
         
         // Controler le type de l'associe
         //
         typeA= associe.getClass().getName();
         if (!typeA.equals(refA)) throw new Throwable("-3.5");
         
         // Ajouter le sous panneau courant au panneau cible
         //
         ajouterPanneau(cle, (HashMap)configCourante);
      }
      
      return true;
   } 
   
   public boolean installerSP (String nomSP, LinkedHashMap description) 
                               throws Throwable { 
   
      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable("-2.1");
      if (description == null) throw new Throwable("-2.2");
      
      // Obtenir la reference du sous panneau cible
      //
      VuePanneauG cible= obtenirSP(nomSP);
      
      // Traiter le cas de l'absence du sous panneau cible
      //
      if (cible == null) throw new Throwable("-3.4");
   
      // Installer la description dans la cible
      //
      return cible.installerSP(description);
   }
   
// ---                                                   Methode deployerSP
     
   public boolean deployerSP (HashMap donnees) throws Throwable {
   
      // Controler la validite du parametre
      //
      if (donnees == null) throw new Throwable("-2.1");
      
      // Appliquer la strategie eventuelle de placement
      //
      LayoutManager strategie= (LayoutManager)donnees.get("placement");
      if (strategie != null) setLayout(strategie);
      
      // Obtenir la description eventuelle de sous panneaux
      //
      Object description= donnees.get("sousPanneaux");
      if (description == null) return true;
      
      // Controler le type de cette description
      //
      String typeD= description.getClass().getName();
      String refD = "java.util.LinkedHashMap";
      if (!typeD.equals(refD)) throw new Throwable("-3.5");
      
      // Parcourir le dictionnaire des sous panneaux du niveau courant
      //
      LinkedHashMap niveauC= (LinkedHashMap) description;
      Iterator i=niveauC.keySet().iterator();
      String cle=null;
      HashMap associe= null, configCourante= null;
      VuePanneauG cible;
      boolean status= false;
   	     	
      while(i.hasNext()) {

         // Acquerir le nom du sous panneau courant
         //
         cle=(String)i.next();
         
         // Acquerir l'associe courant
         //
         associe= (HashMap)niveauC.get(cle);
         
         // Dupliquer l'associe
         //
         configCourante= (HashMap)associe.clone();
         
         // Retirer du clone une eventuelle cle "sousPanneaux" pour eviter
         // une recursion prematuree par les constructeurs
         //
         configCourante.remove("sousPanneaux");
         
         // Ajouter le panneau courant
         //
         ajouterPanneau(cle, configCourante);
         
         // Traiter le cas d'une recursion vers les niveaux inferieurs
         //
         if (associe.containsKey("sousPanneaux")) {
         	
         	// Obtenir la reference du sous panneau courant
         	//
         	cible= obtenirSP(cle);
         	if (cible == null) return false;
         	
         	// Deployer par recursion tous les sous panneaux de niveaux 
         	// inferieurs
         	//
         	status= cible.deployerSP(associe);
         	if (!status) return false;
         }
      } 
      
      return true; 	
   }
   
   public boolean deployerSP (String nomSP, 
                              HashMap donnees) throws Throwable { 
   
      // Controler la validite des parametres
      //
      if (nomSP == null) throw new Throwable("-2.1");
      if (donnees == null) throw new Throwable("-2.2");
      
      // Obtenir la reference du sous panneau cible
      //
      VuePanneauG cible= obtenirSP(nomSP);
      
      // Traiter le cas de l'absence du sous panneau cible
      //
      if (cible == null) throw new Throwable("-3.4");
   
      // Installer les donnees dans la cible
      //
      return cible.deployerSP(donnees);
   } 
   
// ---                                                  Methode reconfigurer  

   public void reconfigurer (HashMap config) throws Throwable {

      setBackground(config);
      setForeground(config);
      setFont(config);
      setLayout(config);
      setImage(config);
      setTitre(config);
   }
   
   public void reconfigurer (String nomSP, 
                             HashMap config) throws Throwable { 
   
      // Controler la validite du parametre
      //
      if (nomSP == null) throw new Throwable("-2.1");
      
      // Obtenir la reference du sous panneau cible
      //
      VuePanneauG cible= obtenirSP(nomSP);
      
      // Traiter le cas de l'absence du sous panneau cible
      //
      if (cible == null) throw new Throwable("-3.4");
   
      // Reconfigurer la cible
      //
      cible.reconfigurer(config);
   } 
} 
